home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / c / ExtrasLib.lha / ExtrasLib / Source / PackData.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-30  |  3.6 KB  |  201 lines

  1. #include <clib/extras/packdata_protos.h>
  2. #include <proto/exec.h>
  3. #include <proto/utility.h>
  4. #include <extras/packdata.h>
  5.  
  6. #include <exec/memory.h>
  7. #include <string.h>
  8. #include <tagitemmacros.h>
  9.  
  10. //#define DEBUG
  11. #include <debug.h>
  12.  
  13. #define ALIGN(I)  (((I)+1)&(~1))
  14. //#define PACKBYTE(PD,DATA) {BYTE data; data=DATA; 
  15.  
  16.  
  17. #define STOREDATA(PDATA,INDEX,VALUE,TYPE)   \
  18. {\
  19.   TYPE *store;\
  20.   INDEX=ALIGN(INDEX);\
  21.   if(PDATA->pd_Data)\
  22.   {\
  23.     store=(TYPE *)(&(PDATA->pd_Data[INDEX]));\
  24.     *store=VALUE;\
  25.   }\
  26.   (INDEX)+=sizeof(TYPE);\
  27. }\
  28.  
  29.  
  30.  
  31. #define STOREBYTE(PDATA,INDEX,VALUE,TYPE)   \
  32. {\
  33.   TYPE *store;\
  34.   if(PDATA->pd_Data)\
  35.   {\
  36.     store=(TYPE *)(&(PDATA->pd_Data[INDEX]));\
  37.     *store=VALUE;\
  38.   }\
  39.   (INDEX)+=sizeof(TYPE);\
  40. }\
  41.  
  42. LONG pd_subPackData(struct PackedData *PD,struct TagItem *TagList);
  43.  
  44.  
  45.  
  46. struct PackedData *pd_PackData(Tag Tags, ...)
  47. {
  48.   struct PackedData pd,*npd;
  49.   ULONG pdo;
  50.   struct TagItem mytags[]=
  51.   {
  52.     PD_StructSize, 0,
  53.     PD_Struct,     0,
  54.     TAG_MORE,      0
  55.   };
  56.   LONG size;
  57.   
  58.   mytags[0].ti_Data=sizeof(pdo),
  59.   mytags[1].ti_Data=&pdo,
  60.   mytags[2].ti_Data=(ULONG)&Tags;
  61.   
  62.   pd.pd_Data=0;
  63.   size=pd_subPackData(&pd,(struct TagItem *)mytags);
  64.   if(size>0)
  65.   {
  66.     if(npd=PD_AllocPackedData(size))
  67.     {
  68.       if(size==pd_subPackData(npd,(struct TagItem *)mytags))
  69.       {
  70.         return(npd);
  71.       }
  72.       else
  73.       PD_FreePackedData(npd);
  74.     }
  75.   }
  76.   return(0);
  77. }
  78.  
  79. LONG pd_subPackData(struct PackedData *PD,struct TagItem *TagList)
  80. {
  81.   LONG i=0,data,aptrsize=0,structsize=0;
  82.   struct TagItem *tag,*tstate;
  83.   
  84.   aptrsize=0;
  85.   
  86.   ProcessTagList(TagList,tag,tstate)
  87.   {
  88.     data=tag->ti_Data;
  89.     
  90. //    DKP("i=%ld\n",i);
  91.     
  92.     switch(tag->ti_Tag)
  93.     {
  94.       case PD_Version: // It's a ULONG
  95.         STOREDATA(PD,i,data,ULONG);
  96.         break;
  97.  
  98.       case PD_BYTE:
  99.         STOREBYTE(PD,i,data,BYTE);
  100.         break;
  101.  
  102.       case PD_UBYTE:
  103.         STOREBYTE(PD,i,data,UBYTE);
  104.         break; 
  105.  
  106.       case PD_WORD:
  107.         STOREDATA(PD,i,data,WORD);
  108.         break;
  109.  
  110.       case PD_UWORD:
  111.         STOREDATA(PD,i,data,UWORD);
  112.         break;
  113.  
  114.       case PD_LONG:
  115.         STOREDATA(PD,i,data,LONG);
  116.         break;
  117.  
  118.       case PD_ULONG:
  119.         STOREDATA(PD,i,data,ULONG);
  120.         break;
  121.  
  122.       case PD_STRPTR:
  123.         if(!data) 
  124.           data=(ULONG)"";
  125.         
  126.         {
  127.           LONG sl;
  128.           
  129.           i=ALIGN(i);
  130.           sl=strlen((STRPTR)data)+1;
  131.           if(PD->pd_Data)
  132.           {
  133.             CopyMem((APTR)data,(APTR)(&PD->pd_Data[i]),sl);
  134.           }
  135.           i+=sl;
  136.         }
  137.         break;
  138.         
  139.       case PD_APTRSize:
  140.         aptrsize=data;
  141.         STOREDATA(PD,i,data,LONG);
  142.         break;
  143.         
  144.       case PD_APTR:
  145.         i=ALIGN(i);
  146.         
  147.         if(PD->pd_Data && data)
  148.         {
  149.           CopyMem((APTR)data,(&PD->pd_Data[i]),aptrsize);
  150.         }
  151.         i+=aptrsize;
  152.         break;
  153.         
  154.       case PD_BufferSize:
  155.         structsize=data;
  156.         break;
  157.         
  158.       case PD_Buffer:
  159.         i=ALIGN(i);
  160.         
  161.         STOREDATA(PD,i,structsize,LONG);
  162.         if(PD->pd_Data && data)
  163.         {
  164.           CopyMem((APTR)data,(&PD->pd_Data[i]),structsize);
  165.         }
  166.         i+=structsize;
  167.         break;  
  168.         
  169.       default:
  170. //        DKP("Unknow Tag %ld, %ld (%08lx, %08lx)\n",tag[0],tag[0]);
  171.         /* ERROR */
  172.         return(-1);
  173.     }
  174.   }
  175.   return(i);
  176. }  
  177.  
  178. struct PackedData *pd_AllocPackedData(ULONG Size)
  179. {
  180.   struct PackedData *pd;
  181.   if(pd=AllocVec(sizeof(*pd),MEMF_CLEAR|MEMF_PUBLIC))
  182.   {
  183.     pd->pd_DataSize=Size;
  184.     if(pd->pd_Data=AllocVec(Size,MEMF_CLEAR|MEMF_PUBLIC))
  185.     {
  186.       return(pd);
  187.     }
  188.     FreeVec(pd);
  189.   }
  190.   return(0);
  191. }
  192.  
  193. void pd_FreePackedData(struct PackedData *PD)
  194. {
  195.   if(PD)
  196.   {
  197.     FreeVec(PD->pd_Data);
  198.     FreeVec(PD);
  199.   }
  200. }
  201.